<template>
  <div class="Wangeditor-box">
    <Toolbar class="Wangeditor-Toolbar" :editor="editorRef" :defaultConfig="toolbarConfig" :mode="mode" />
    <Editor
      class="Wangeditor-Editor"
      v-model="editValue"
      :defaultConfig="editorConfig"
      :mode="mode"
      @onCreated="handleCreated"
      @onChange="handleChange"
      @customPaste="customPaste"
    />
  </div>
</template>
<script setup>
// 文档地址：https://www.wangeditor.com/v5/for-frame.html
import "@wangeditor/editor/dist/css/style.css"; // 引入 css
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
import { Boot } from "@wangeditor/editor";
import attachmentModule from "@wangeditor/plugin-upload-attachment"; //附件上传插件（如果项目不需要使用则注释相关代码）
import { onBeforeUnmount, shallowRef, getCurrentInstance, computed } from "vue";
import { ElMessage } from "element-plus";
import axios from "axios";

const props = defineProps({
  mode: {
    default: "default", // default：默认展示全部菜单；simple：精简模式
    type: String,
  },
  modelValue: {
    type: String,
    default: "",
  },
  token: {
    type: String,
    default: "",
  },
});

// 编辑器实例，必须用 shallowRef
const editorRef = shallowRef();

const editValue = computed({
  get() {
    return props.modelValue;
  },
  set(value) {
    // emits('update:modelValue', value);
  },
});

const emits = defineEmits(["update:modelValue"]);

// 注册。要在创建编辑器之前注册，且只能注册一次，不可重复注册。(这里用于附件上传插件的注册，如果不需要则注释)
if (Boot.plugins.length < 13) {
  //判断如果已经插入进去，不在二次插入
  Boot.registerModule(attachmentModule);
}

const toolbarConfig = {
  insertKeys: {
    index: 21, // 自定义插入的位置
    keys: ["uploadAttachment"], // “上传附件”菜单
  },
  excludeKeys: ["fontFamily"], // 由于某些字体不能商用，所以这里直接隐藏所有字体选择
};

// 编辑器配置
const editorConfig = {
  placeholder: "请输入内容...",
  autoFocus: false,
  // 在编辑器中，点击选中“附件”节点时，要弹出的菜单
  /* hoverbarKeys: {
		attachment: {
			menuKeys: ['downloadAttachment'] // “下载附件”菜单
		}
	}, */
  // 所有的菜单配置，都要在 MENU_CONF 属性下
  MENU_CONF: {
    // 配置图片上传
    uploadImage: {
      server: "/api/common/upload-file?module=enterprise&size=10", //上传接口地址
      headers: {
        Authorization: props.token,
      },
      metaWithUrl: true, // 参数拼接到 url 上
      fieldName: "file", //上传文件名
      methods: "post",
      allowedFileTypes: ["image/*"],
      maxFileSize: 10 * 1024 * 1024, // 10M 单个文件的最大体积限制，默认为 2M
      onSuccess(file, res) {
        if (res.code == 200) {
          ElMessage.success(`${file.name} 上传成功`);
        } else {
          ElMessage.error(res.msg || "上传失败");
        }
      },
      onFailed(file, res) {
        if (res.code == 200) {
          ElMessage.success(`${file.name} 上传成功`);
        } else {
          ElMessage.error(res.msg || "上传失败");
        }
      },
      // 上传错误，或者触发 timeout 超时
      onError(file, err, res) {
        if (file.size / 1024 / 1024 > 10) {
          ElMessage.warning("上传文件超过10M");
          return;
        }
        ElMessage.error(res.msg || "上传失败");
      },
      customInsert(res, insertFn) {
        if (res.code == 200) {
          insertFn(res.data.absolutePath);
        }
      },
    },
    // 配置视频上传
    uploadVideo: {
      server: "/api/common/upload-file?module=enterprise&size=100", //上传接口地址
      headers: {
        Authorization: props.token,
      },
      // maxNumberOfFiles: 1, // 最多可上传几个文件，默认为 5
      fieldName: "file", //上传文件名
      maxFileSize: 100 * 1024 * 1024, // 100M 单个文件的最大体积限制，默认为 2M
      onSuccess(file, res) {
        if (res.code == 200) {
          ElMessage.success(`${file.name} 上传成功`);
        } else {
          ElMessage.error(res.msg || "上传失败");
        }
      },
      onFailed(file, res) {
        if (res.code == 200) {
          ElMessage.success(`${file.name} 上传成功`);
        } else {
          ElMessage.error(res.msg || "上传失败");
        }
      },
      // 上传错误，或者触发 timeout 超时
      onError(file, err, res) {
        if (file.size / 1024 / 1024 > 100) {
          ElMessage.warning("上传文件超过100M");
          return;
        }
        ElMessage.error(res.msg || "上传失败");
      },
      customInsert(res, insertFn) {
        if (res.code == 200) {
          insertFn(res.data.absolutePath);
        }
      },
    },
    // 附件上传
    uploadAttachment: {
      server: "/api/common/upload-file?module=enterprise&size=10", // 服务端地址
      timeout: 10 * 1000, // 5s
      fieldName: "file",
      headers: {
        Authorization: props.token,
      },
      maxFileSize: 10 * 1024 * 1024, // 10M
      onSuccess(file, res) {
        if (res.code == 200) {
          ElMessage.success(`${file.name} 上传成功`);
        } else {
          ElMessage.error(res.msg || "上传失败");
        }
      },
      onFailed(file, res) {
        if (res.code == 200) {
          ElMessage.success(`${file.name} 上传成功`);
        } else {
          ElMessage.error(res.msg || "上传失败");
        }
      },
      // 上传错误，或者触发 timeout 超时
      onError(file, err, res) {
        if (file.size / 1024 / 1024 > 10) {
          ElMessage.warning("上传文件超过10M");
          return;
        }
        ElMessage.error(res.msg || "上传失败");
      },
      customInsert(res, file, insertFn) {
        if (res.code == 200) {
          ElMessage.success(`${file.name} 上传成功`);
          insertFn(`附件-${file.name}`, res.data.absolutePath);
        } else {
          ElMessage.error(res.msg || "上传失败");
        }
      },
      // 插入到编辑器后的回调
      onInsertedAttachment(elem) {
        // console.log('inserted attachment', elem);
      },
    },
  },
};

const handleCreated = (editor) => {
  editorRef.value = editor; // 记录 editor 实例，重要！
};

// 内容改变
const handleChange = (editor) => {
  if (editor.getText().length > 10000) {
    console.log("文本超长");
  }
  emits("update:modelValue", editor.getHtml());
};

// 粘贴事件
const customPaste = (editor, event, callback) => {
  // 去掉格式
  const text = event.clipboardData.getData("text/plain"); // 获取粘贴的纯文本
  editor.insertText(text);
  event.preventDefault();
  callback(false);
};

// 组件销毁时，也及时销毁编辑器
onBeforeUnmount(() => {
  const editor = editorRef.value;
  if (editor == null) return;
  editor.destroy();
});
</script>

<style lang="scss">
.Wangeditor-box {
  width: 100%;
  min-height: 100%;
  display: flex;
  flex-direction: column;
  border: 1px solid #ebeef5;

  .Wangeditor-Toolbar {
    border-bottom: 1px solid #ebeef5;
  }

  .Wangeditor-Editor {
    min-height: 200px;
    flex: 1;
  }
}
</style>
